package com.ls.spring.framework.webmvc.servlet;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.RandomAccessFile;
import java.nio.charset.StandardCharsets;
import java.util.Map;
import java.util.Optional;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author 挥之以墨
 */
public class MyView {

    /**
     * 预编译匹配￥{}的正则表达式
     */
    private static final Pattern PATTERN = Pattern.compile("￥\\{[^}]+}", Pattern.CASE_INSENSITIVE);
    /**
     * 视图文件
     */
    private File viewFile;

    public MyView(File viewFile) {
        this.viewFile = viewFile;
    }


    public void render(Map<String, ?> model, HttpServletRequest req, HttpServletResponse resp) throws Exception {
        StringBuilder sb = new StringBuilder();
        RandomAccessFile ra = new RandomAccessFile(viewFile, "r");

        String line;
        while ((line = ra.readLine()) != null) {
            line = new String(line.getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8);
            // 替换模板值，忽略大小写
            Matcher matcher = PATTERN.matcher(line);
            while (matcher.find()) {
                String paramName = matcher.group().replaceAll("￥\\{|}", "");
                String paramValue = Optional.ofNullable(model)
                        .map(m -> m.get(paramName))
                        .map(Object::toString)
                        .orElse("");
                line = matcher.replaceFirst(makeStringForRegExp(paramValue));
                matcher = PATTERN.matcher(line);
            }
            sb.append(line);
        }
        resp.setCharacterEncoding("UTF-8");
        resp.getWriter().write(sb.toString());
    }

    /**
     * 处理特殊字符
     */
    public static String makeStringForRegExp(String str) {
        return str.replace("\\", "\\\\").replace("*", "\\*")
                .replace("+", "\\+").replace("|", "\\|")
                .replace("{", "\\{").replace("}", "\\}")
                .replace("(", "\\(").replace(")", "\\)")
                .replace("^", "\\^").replace("$", "\\$")
                .replace("[", "\\[").replace("]", "\\]")
                .replace("?", "\\?").replace(",", "\\,")
                .replace(".", "\\.").replace("&", "\\&");
    }
}
